//
// Created by 86180 on 2025/1/24.
//

#ifndef AVLTREE_RBTTIMER_H
#define AVLTREE_RBTTIMER_H
#include <functional>
#include <chrono>
#include <utility>
#include <mutex>
#include "RBTree.h"

using TimerCallBack = std::function<void(void*)>;
struct Task{
    int64_t id;
    int64_t expire; //到期时间戳
    void* context;
    TimerCallBack callback;
    uint64_t interval; //重复间隔,0表示一次性任务
    Task(int64_t id,int64_t expire,uint64_t interval,TimerCallBack callBack,void* ctx)
        :id(id),expire(expire),interval(interval),callback(callBack),context(ctx){} //要用移动
};

class Timer{
private:
    RBTree<int64_t,Task*> tree;
    int64_t nextid = 0;
    std::mutex mtx;
public:
    int64_t addtask(int64_t delay, TimerCallBack cb, void* ctx = nullptr, bool repeat = false, uint64_t interval = 0){
        std::lock_guard<std::mutex> lg(mtx);
        int64_t id = ++nextid;
        auto now = getCurrentTime();
        int64_t expire = now + delay;
        auto task = new Task(id, expire, repeat ? interval : 0, cb, ctx);
        tree.insert(expire,task);
        return id;
    }

    void cancel(int64_t taskid){  //树没写迭代器，所以这里有点麻烦
        std::lock_guard<std::mutex> lg(mtx);
        auto list = tree.inorder();
        for(auto item:list){
            if (item->value->id == taskid){
                tree.remove(item->key);
                delete item->value;
                return;
            }
        }
    }
    //这个函数配合其它模块，如epoll_wait的等待时间
    int64_t  tick(){
        auto now = getCurrentTime();
        auto list = tree.inorder();

        //收集所有到期任务(可能会有多个)
        std::vector<RBTreeNode<int64_t,Task*>*> v;
        for(auto item:list){
            if (item->key <= now){
                v.push_back(item);
            }else{
                break;
            }
        }
        //执行
        for(auto item:v){
            auto* task = item->value;
            tree.remove(item->key);
            if (task->callback){
                task->callback(task->context);
            }
            //重复任务
            if (task->interval > 0) {
                task->expire = now + task->interval;
                tree.insert(task->expire,task);
            }else{
                delete task;
            }
        }

        //返回下一个任务所需等待时间
        auto next = tree.getminimum();
        return next == nullptr?-1:next->key;
    }

    static int64_t getCurrentTime(){
        return static_cast<int64_t>(std::chrono::system_clock::now().time_since_epoch().count());
    }
};

#endif //AVLTREE_RBTTIMER_H
